//
//  VisitorObjects.m
//  Charles
//
//  Created by Leo on 2019/7/15.
//  Copyright © 2019 charles. All rights reserved.
//

#import "VisitorObjects.h"
@implementation VEntry

- (NSString *)getName {
    return nil;
}

- (NSInteger)getSize {
    return 0;
}

- (void)printList {
    [self printList:@""];
}

- (void)printList:(NSString *)prefix {
    
}

- (VEntry *)add:(VEntry *)entry {
    return nil;
}

- (NSString *)toString {
    return [NSString stringWithFormat:@"%@ (%zi)",[self getName],[self getSize]];
}

@end

@interface VFile ()

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger size;

@end

@implementation VFile

- (instancetype)initWithName:(NSString *)name size:(NSInteger)size {
    if (self = [super init]) {
        self.name = name;
        self.size = size;
    }
    return self;
}

- (NSString *)getName {
    return _name;
}

- (NSInteger)getSize {
    return _size;
}

- (void)printList:(NSString *)prefix {
    NSLog(@"%@/%@",prefix,self.toString);
}

- (void)accept:(id<Visitor>)visitor {
    [visitor visitFile:self];
}

@end

@interface VDirectory ()

@property (nonatomic, strong) NSString *name;

@end

@implementation VDirectory

- (instancetype)initWithName:(NSString *)name {
    if (self = [super init]) {
        self.name = name;
        self.directory = [[NSMutableArray alloc]initWithCapacity:0];
    }
    return self;
}

- (NSString *)getName {
    return _name;
}

- (NSInteger)getSize {
    __block NSInteger size = 0;
    [self.directory enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        VEntry *entry = (VEntry *)obj;
        size += [entry getSize];
    }];
    return size;
}

- (VEntry *)add:(VEntry *)entry {
    [self.directory addObject:entry];
    return self;
}

- (void)printList:(NSString *)prefix {
    NSLog(@"%@/%@",prefix,self.toString);
    [self.directory enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        VEntry *entry = (VEntry *)obj;
        NSString *str = [NSString stringWithFormat:@"%@/%@",prefix,self.name];
        [entry printList:str];
    }];
}

- (void)accept:(id<Visitor>)visitor {
    [visitor visitDirectory:self];
}

@end

@interface ListVisitor ()

@property (strong,nonatomic) NSString *currentDir;

@end

@implementation ListVisitor

- (instancetype)init {
    if (self = [super init]) {
        self.currentDir = @"";
    }
    return self;
}

- (void)visitFile:(VFile *)file {
    NSLog(@"%@/%@",self.currentDir,file.toString);
}

- (void)visitDirectory:(VDirectory *)directory {
    NSLog(@"%@/%@",self.currentDir,directory.toString);
    NSString *saveDir = self.currentDir;
    self.currentDir = [NSString stringWithFormat:@"%@/%@",self.currentDir,directory.getName];
    [directory.directory enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        id<Element> entry = obj;
        [entry accept:self];
    }];
    self.currentDir = saveDir;
}

@end
